package com.fangcun.service.api.impl;

import java.util.Date;
import java.util.List;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fangcun.bean.api.floor.request.FloorDetailRequest;
import com.fangcun.bean.api.floor.request.FloorMyReserveRequest;
import com.fangcun.bean.api.floor.request.FloorReserveRequest;
import com.fangcun.bean.api.floor.request.FloorRoomSearchRequest;
import com.fangcun.bean.api.floor.response.FloorMyReserveResponse;
import com.fangcun.bean.api.floor.response.FloorReserveResponse;
import com.fangcun.bean.api.floor.response.FloorResponse;
import com.fangcun.bean.api.floor.response.FloorRoomDetailResponse;
import com.fangcun.bean.api.floor.response.TeahouseResponse;
import com.fangcun.bean.sys.PageBean;
import com.fangcun.common.canstant.ErrCode;
import com.fangcun.common.canstant.PublicConstant;
import com.fangcun.common.enums.OrderStatusEnum;
import com.fangcun.common.exception.ProAffairException;
import com.fangcun.common.exception.ProRunTimeException;
import com.fangcun.common.util.BeanMapper;
import com.fangcun.common.util.PublicMethod;
import com.fangcun.common.util.base.BaseService;
import com.fangcun.entity.FloorReserve;
import com.fangcun.entity.User;
import com.fangcun.mapper.FloorMapper;
import com.fangcun.mapper.FloorReserveMapper;
import com.fangcun.mapper.FloorRoomMapper;
import com.fangcun.mapper.TeahouseMapper;
import com.fangcun.mapper.UserMapper;
import com.fangcun.service.api.FloorService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

/**
 * @作者： 陳曉鬆 @时间： 2021年1月4日 - 上午10:05:02 @description：->
 */
@Service("floorService")
public class FloorServiceImpl extends BaseService implements FloorService {

	@Autowired
	private TeahouseMapper teahouseMapper;
	@Autowired
	private FloorMapper floorMapper;
	@Autowired
	private FloorRoomMapper floorRoomMapper;
	@Autowired
	private FloorReserveMapper floorReserveMapper;
	@Autowired
	private UserMapper userMapper;

	@Override
	public TeahouseResponse selectRooms(FloorRoomSearchRequest request) throws ProAffairException {
		TeahouseResponse response = teahouseMapper.selectById(request);
		if (response == null) {
			throw new ProAffairException(ErrCode.NO_DATA.getReturnCode(), ErrCode.NO_DATA.getReturnMsg());
		}
		response.setStartTime(request.getStartTime());
		response.setEndTime(request.getEndTime());
		response.setLongitude(request.getLongitude());
		response.setLatitude(request.getLatitude());

		List<FloorResponse> floorList = floorMapper.selectByTeahouseId(response.getId());
		if (floorList == null || floorList.size() == 0) {
			throw new ProRunTimeException(ErrCode.NO_DATA.getReturnCode(), ErrCode.NO_DATA.getReturnMsg());
		}

		for (FloorResponse floor : floorList) {
			request.setTeahouseId(floor.getId());
			floor.setFloorRooms(floorRoomMapper.selectByTeahouseIdAndTime(request));
		}

		response.setFloors(floorList);
		return response;
	}

	@Override
	public FloorRoomDetailResponse selectRoomsDetail(FloorDetailRequest request) throws ProAffairException {
		request.setNowTime(new Date());
		FloorRoomDetailResponse response = floorRoomMapper.selectByIdAndTime(request);
		if (response == null) {
			throw new ProRunTimeException(ErrCode.NO_DATA.getReturnCode(), ErrCode.NO_DATA.getReturnMsg());
		}
		response.setStartTime(request.getStartTime());
		response.setEndTime(request.getEndTime());
		response.setLongitude(request.getLongitude());
		response.setLatitude(request.getLatitude());
		return response;
	}

	@Override
	@Transactional
	public FloorReserveResponse reserve(FloorReserveRequest request) throws ProAffairException {
		synchronized (request.getFloorRoomId()) {
			int db = 12;
			String key = PublicMethod.getMd5(request.toString(), 1, true);
			if (redisService.get(db, key) != null) {
				throw new ProRunTimeException(ErrCode.FAIL.getReturnCode(), "重复预定");
			}
			redisService.set(db, key, "1", 60);
			try {
				FloorDetailRequest queryDetail = new FloorDetailRequest();
				queryDetail.setNowTime(request.getStartTime());
				queryDetail.setStartTime(request.getStartTime());
				queryDetail.setEndTime(request.getEndTime());
				queryDetail.setFloorRoomId(request.getFloorRoomId());
				FloorRoomDetailResponse detail = selectRoomsDetail(queryDetail);
				if (detail.getIsReserve() == 0) {
					throw new ProRunTimeException(ErrCode.FAIL.getReturnCode(), "不可预定");
				}
				if (detail.getType() == 2 && request.getPeopleNumber() <= 0) {// 大厅
					throw new ProRunTimeException(ErrCode.FAIL.getReturnCode(), "预定人数必须大于0、不可预定");
				}
				if (detail.getType() == 2 && detail.getNowPeopleNumber() + request.getPeopleNumber() > detail.getMaxPeople()) {// 大厅
					throw new ProRunTimeException(ErrCode.FAIL.getReturnCode(), "大厅超过人数限制、不可预定");
				}
				if (detail.getReserveVip() == 1) {
					User user = userMapper.selectByPrimaryKey(request.getUserId());
					if (user == null) {
						throw new ProRunTimeException(ErrCode.NO_DATA.getReturnCode(), "用户不存在");
					}
					if (user.getVipLevel() == 0) {
						throw new ProRunTimeException(ErrCode.FAIL.getReturnCode(), "该用户非会员、不可预定");
					}
				}
				FloorReserve reserve = BeanMapper.map(detail, FloorReserve.class);
				reserve.setId(null);
				reserve.setUserId(request.getUserId());
				reserve.setReserveNumber(PublicMethod.getOrderNumber(PublicConstant.RESERVE, null));
				reserve.setPeopleNumber(request.getPeopleNumber());
				reserve.setStatus(OrderStatusEnum.RESERVE_ORDER_STATUS_1.getStatus());
				reserve.setContactName(request.getContactName());
				reserve.setContactPhone(request.getContactPhone());
				if (floorReserveMapper.insertSelective(reserve) <= 0) {
					throw new ProRunTimeException(ErrCode.FAIL.getReturnCode(), "预定失败，请选择其他条件重试");
				}
				FloorReserveResponse response = BeanMapper.map(reserve, FloorReserveResponse.class);
				return response;
			} catch (ProAffairException e) {
				redisService.remove(db, key);
				throw new ProRunTimeException(e.getErrorCode(), e.getErrorMsg());
			}
		}
	}

	@Override
	public PageInfo<FloorMyReserveResponse> myReserveList(PageBean<FloorMyReserveRequest> request) throws ProAffairException {
		PageHelper.startPage(request.getPageNum(), request.getPageSize());
		List<FloorMyReserveResponse> list = floorReserveMapper.myList(request.getParam());
		if (list == null || list.size() == 0) {
			throw new ProRunTimeException(ErrCode.NO_DATA.getReturnCode(), ErrCode.NO_DATA.getReturnMsg());
		}
		return new PageInfo<>(list);
	}

	@Override
	@Transactional
	public void reserveUpdateStatus(FloorReserve request) throws ProAffairException {
		if (floorReserveMapper.updateByPrimaryKeySelective(request) <= 0) {
			throw new ProRunTimeException(ErrCode.FAIL.getReturnCode(), ErrCode.FAIL.getReturnMsg());
		}
	}

}
